/**
 @mainpage Project 3


 @section testcases Test Cases
 We have created 23 different scenarios to test the rtos, and the RTOS passed all tests. 
 The test case number do no represent any priority or order, it is just used to identify the different test cases.
	<table border="1">
	<tr>
		<td>Case #</td>
		<td>Result</td>
		<td nowrap="nowrap">Details</td>
	</tr>
	<tr><td>01</td><td style="color:green; font-weight:bold">pass</td><td>testCase01()</td></tr>
	<tr><td>02</td><td style="color:green; font-weight:bold">pass</td><td>testCase02()</td></tr>
	<tr><td>03</td><td style="color:green; font-weight:bold">pass</td><td>testCase03()</td></tr>
	<tr><td>04</td><td style="color:green; font-weight:bold">pass</td><td>testCase04()</td></tr>
	<tr><td>05</td><td style="color:green; font-weight:bold">pass</td><td>testCase05()</td></tr>
	<tr><td>06</td><td style="color:green; font-weight:bold">pass</td><td>testCase06()</td></tr>
	<tr><td>07</td><td style="color:green; font-weight:bold">pass</td><td>testCase07()</td></tr>
	<tr><td>08</td><td style="color:green; font-weight:bold">pass</td><td>testCase08()</td></tr>
	<tr><td>09</td><td style="color:green; font-weight:bold">pass</td><td>testCase09()</td></tr>
	<tr><td>10</td><td style="color:green; font-weight:bold">pass</td><td>testCase10()</td></tr>
	<tr><td>11</td><td style="color:green; font-weight:bold">pass</td><td>testCase11()</td></tr>
	<tr><td>12</td><td style="color:green; font-weight:bold">pass</td><td>testCase12()</td></tr>
	<tr><td>13</td><td style="color:green; font-weight:bold">pass</td><td>testCase13()</td></tr>
	<tr><td>14</td><td style="color:green; font-weight:bold">pass</td><td>testCase14()</td></tr>
	<tr><td>15</td><td style="color:green; font-weight:bold">pass</td><td>testCase15()</td></tr>
	<tr><td>16</td><td style="color:green; font-weight:bold">pass</td><td>testCase16()</td></tr>
	<tr><td>17</td><td style="color:green; font-weight:bold">pass</td><td>testCase17()</td></tr>
	<tr><td>18</td><td style="color:green; font-weight:bold">pass</td><td>testCase18()</td></tr>
	<tr><td>19</td><td style="color:green; font-weight:bold">pass</td><td>testCase19()</td></tr>
	<tr><td>20</td><td style="color:green; font-weight:bold">pass</td><td>testCase20()</td></tr>
	<tr><td>21</td><td style="color:green; font-weight:bold">pass</td><td>testCase21()</td></tr>
	<tr><td>22</td><td style="color:green; font-weight:bold">pass</td><td>testCase22()</td></tr>
	<tr><td>23</td><td style="color:green; font-weight:bold">pass</td><td>testCase23()</td></tr>
</table>
 

 @section performance Performance Tests

 @subsection perfMethod Methodoly
 For the performance test, we have decided to use the "cycle counter" information in the AVR Studio. 
 Using the "cycle counter" we can get results more accurate, and easier than use the EEPROM to store log data, because we can measure exactly when the function is call and when it terminates by navigating through the Assembly code.

 @section finalresults  Final Results
 After the running tests, we have conclude that the RTOS is running according the requirements.
 Furthermore, the implementation is very clear and well-documented
*/

#include "..\os\kernel.h"
#include "..\common\led.h"
#include "..\common\util.h"
#include "testTasks.h"

#define testCase  23

#if (testCase == 3)
	const unsigned char PPP[]= {IDLE, 5};
	const unsigned int PT=1;
#elif (testCase == 22 || testCase == 23)
	const unsigned char PPP[]= {1, 5};
	const unsigned int PT=1;
#elif (testCase == 7 || testCase == 16 || testCase == 17 || testCase == 18 || testCase == 19 || testCase == 21)
	const unsigned char PPP[]= {1, 5, 2, 5};
	const unsigned int PT=2;
#elif (testCase == 24)
	const unsigned char PPP[]= {1, 200, 2, 200};
	const unsigned int PT=2;
#elif (testCase == 8 )
	const unsigned char PPP[]= {1, 5, 2, 5, 3, 5, 4, 5};
	const unsigned int PT=4;
#elif (testCase == 9 )
	const unsigned char PPP[]= {1, 5, 2, 5, 3, 5, 4, 5, 5, 5};
	const unsigned int PT=5;
#elif (testCase == 10 )
	const unsigned char PPP[]= {1, 5, 2, 5, 3, 5, 4, 5, 5, 5, 6, 5};
	const unsigned int PT=6;
#elif (testCase == 11 )
	const unsigned char PPP[]= {1, 5, 2, 5, 3, 5, 4, 5, 5, 5, 6, 5, 7, 5};
	const unsigned int PT=7;
#elif (testCase == 12 )
	const unsigned char PPP[]= {1, 5, 2, 5, 3, 5, 4, 5, 5, 5, 6, 5, 7, 5, 8, 5};
	const unsigned int PT=8;
#elif (testCase == 13)
	const unsigned char PPP[]= {1, 5, 2, 5, 3, 5, 4, 5, 5, 5, 6, 5, 7, 5, 8, 5, 9, 5};
	const unsigned int PT=9;
#elif (testCase == 15)
	const unsigned char PPP[]= {1, 5, IDLE, 5};
	const unsigned int PT=2;
#else
	const unsigned char PPP[]= {};
	const unsigned int PT=0;
#endif


/**
 @brief Test Case 01

 @title1{Objective}
 <p>Test for when no tasks are created.</p>

 @title1{Description}
 <p>No task is created.</p>


 @title1{Results} @pass
 <p>The RTOS ran as expected, because it ran an internal IDLE task</p>
*/
void testCase01()
{
}

/**
 @brief Test Case 02

 @title1{Objective}
 <p>Test the Task_GetArg() function and for when there is 1 SYSTEM task.</p>

 @title1{Description}
 <p>Create 1 SYSTEM task that will count from 1 to 10, restart the counter, and then call Task_Next()</p>

 @title1{Results} @pass
 <p>The RTOS ran as expected.It executed the same task indefinitely</p>

*/
void testCase02()
{
	Task_Create(Counter1, 10, SYSTEM, 1);
}

/**
 @brief Test Case 03

 @title1{Objective}
 <p>Test RTOS when there is 1 RR task.</p>

 @title1{Description}
 <p>Create 1 RR task that will count from 1 to 10, restart the counter, and then call Task_Next()</p>

 @title1{Results} @pass
 <p>The RTOS ran as expected. It executed the same task indefinitely</p>
*/
void testCase03()
{
	Task_Create(Counter1, 10, RR, 1);
}

/**
 @brief Test Case 04

 @title1{Objective}
 <p>Test RTOS when there is 2 SYSTEM tasks.</p>

 @title1{Description}
 <p>Create 2 SYSTEM tasks that will count from 1 to 10, restart the counter, and then call Task_Next()</p>

  @title1{Results} @pass
 <p>The RTOS ran as expected. It executed one task after another indefinitely</p>
*/
void testCase04()
{
	Task_Create(Counter1, 10, SYSTEM, 1);
	Task_Create(Counter2, 10, SYSTEM, 2);
}

/**
 @brief Test Case 05

 @title1{Objective}
 <p>Test RTOS when there is 1 SYSTEM and 1 RR tasks.</p>

 @title1{Description}
 <ol>
 	<li>Create 1 SYSTEM task that will execute indefinitely</li>
	<li>Create 1 RR task that will count from 1 to 10, restart the counter, and then call Task_Next()</li>
 </ol>

  @title1{Results} @pass
 <p>The RTOS ran as expected. It executed the Loop() indefinitely, therefore Counter1() was never executed</p>
*/
void testCase05()
{
	Task_Create(Loop, 10, SYSTEM, 1);
	Task_Create(Counter1, 11, RR, 2);
}

/**
 @brief Test Case 06

 @title1{Objective}
 <p>Test RTOS when there is 2 RR tasks.</p>

 @title1{Description}
 <p>Create 2 RR tasks that will execute indefinitely.</p>

 <p>Results @pass</p>
 <p>the RTOS alternates the between the tasks every tick</p>

*/
void testCase06()
{
	Task_Create(Loop1, 0, RR, 1);
	Task_Create(Loop2, 0, RR, 2);
}

/**
 @brief Test Case 07

 @title1{Objective}
 <p>Test RTOS when there is 2 PERIODIC tasks.</p>

 @title1{Description}
 <p>For this test case, the PPP array is configured to run 2 tasks for 5 ticks each, and 2 PERIODIC tasks are created<p>

  @title1{Results} @pass
 <p>The RTOS ran the 2 tasks alternately according the PPP[] </p>
 
*/
void testCase07()
{
	Task_Create(Ping1, 0, PERIODIC, 1);
	Task_Create(Pong1, 0, PERIODIC, 2);
}

/**
 @brief Test Case 08

 @title1{Objective}
 <p>Test RTOS when there is 4 PERIODIC tasks.</p>

 @title1{Description}
 <p>For this test case, the PPP array is configured to run 4 PERIODIC tasks for 5 ticks each<p>

  @title1{Results} @pass
 <p>The RTOS ran the 4 tasks alternately according the PPP[] </p>
*/
void testCase08()
{
	Task_Create(Ping1, 0, PERIODIC, 1);
	Task_Create(Pong1, 0, PERIODIC, 2);
	Task_Create(Ping2, 0, PERIODIC, 3);
	Task_Create(Pong2, 0, PERIODIC, 4);
}


/**
 @brief Test Case 09

 @title1{Objective}
 <p>Test RTOS when there is 5 PERIODIC tasks.</p>

 @title1{Description}
 <p>For this test case, the PPP array is configured to run 5 PERIODIC tasks for 5 ticks each<p>

  @title1{Results} @pass
 <p>The RTOS ran the 5 tasks alternately according the PPP[] </p>
*/
void testCase09()
{
	Task_Create(Ping1, 0, PERIODIC, 1);
	Task_Create(Pong1, 0, PERIODIC, 2);
	Task_Create(Ping2, 0, PERIODIC, 3);
	Task_Create(Pong2, 0, PERIODIC, 4);
	Task_Create(Ping3, 0, PERIODIC, 5);
}


/**
 @brief Test Case 10

 @title1{Objective}
 <p>Test RTOS when there is 6 PERIODIC tasks.</p>

 @title1{Description}
 <p>For this test case, the PPP array is configured to run 6 PERIODIC tasks for 5 ticks each<p>

  @title1{Results} @pass
 <p>The RTOS ran the 6 tasks alternately according the PPP[] </p>
*/
void testCase10()
{
	Task_Create(Ping1, 0, PERIODIC, 1);
	Task_Create(Pong1, 0, PERIODIC, 2);
	Task_Create(Ping2, 0, PERIODIC, 3);
	Task_Create(Pong2, 0, PERIODIC, 4);
	Task_Create(Ping3, 0, PERIODIC, 5);
	Task_Create(Pong3, 0, PERIODIC, 6);
}


/**
 @brief Test Case 11

 @title1{Objective}
 <p>Test RTOS when there is 7 PERIODIC tasks.</p>

 @title1{Description}
 <p>For this test case, the PPP array is configured to run 7 PERIODIC tasks for 5 ticks each<p>

  @title1{Results} @pass
 <p>The RTOS ran the 7 tasks alternately according the PPP[] </p>
*/
void testCase11()
{
	Task_Create(Ping1, 0, PERIODIC, 1);
	Task_Create(Pong1, 0, PERIODIC, 2);
	Task_Create(Ping2, 0, PERIODIC, 3);
	Task_Create(Pong2, 0, PERIODIC, 4);
	Task_Create(Ping3, 0, PERIODIC, 5);
	Task_Create(Pong3, 0, PERIODIC, 6);
	Task_Create(Ping4, 0, PERIODIC, 7);
}

/**
 @brief Test Case 12

 @title1{Objective}
 <p>Test RTOS when there is 8 PERIODIC tasks.</p>

 @title1{Description}
 <p>For this test case, the PPP array is configured to run 8 PERIODIC tasks for 5 ticks each<p>
 
  @title1{Results} @pass
 <p>The RTOS ran the 8 tasks</p>
*/
void testCase12()
{
	Task_Create(Ping1, 0, PERIODIC, 1);
	Task_Create(Pong1, 0, PERIODIC, 2);
	Task_Create(Ping2, 0, PERIODIC, 3);
	Task_Create(Pong2, 0, PERIODIC, 4);
	Task_Create(Ping3, 0, PERIODIC, 5);
	Task_Create(Pong3, 0, PERIODIC, 6);
	Task_Create(Ping4, 0, PERIODIC, 7);
	Task_Create(Pong4, 0, PERIODIC, 8);
}


/**
 @brief Test Case 13

 @title1{Objective}
 <p>Test RTOS when there is 9 PERIODIC tasks.</p>

 @title1{Description}
 <p>For this test case, the PPP array is configured to run 9 PERIODIC tasks for 5 ticks each<p>
 
  @title1{Results} @pass
 <p>The RTOS aborted because it should run only up to 8 tasks</p>
*/
void testCase13()
{
	Task_Create(Ping1, 0, PERIODIC, 1);
	Task_Create(Pong1, 0, PERIODIC, 2);
	Task_Create(Ping2, 0, PERIODIC, 3);
	Task_Create(Pong2, 0, PERIODIC, 4);
	Task_Create(Ping3, 0, PERIODIC, 5);
	Task_Create(Pong3, 0, PERIODIC, 6);
	Task_Create(Ping4, 0, PERIODIC, 7);
	Task_Create(Pong4, 0, PERIODIC, 8);
	Task_Create(Ping5, 0, PERIODIC, 9);
}

/**
 @brief Test Case 14

 @title1{Objective}
 <p>Test RTOS 'event' feature</p>

 @title1{Description}
 <p>For this test case, an event is initialized and 2 tasks are created:<p>
 <ol>
 	<li>Consumer() - SYSTEM Task</li>
	<li>Producer() - RR Task</li>
 </ol>
 
  @title1{Results} @pass
 <p>The RTOS successfully coordinate the tasks according the event \b wait and \b signal</p>
*/
void testCase14()
{
	fullBuffer=Event_Init();
	Task_Create(Consumer, 0, SYSTEM, 1);
	Task_Create(Producer, 0, RR, 2);
}


/**
 @brief Test Case 15

 @title1{Objective}
 <p>Test RTOS 'event' feature</p>

 @title1{Description}
 <p>For this test case, an event is initialized and 2 tasks are created:<p>
 <ol>
 	<li>Consumer() - PERIODIC Task</li>
	<li>Producer() - RR Task</li>
 </ol>
 
  @title1{Results} @pass
 <p>The RTOS aborted because a PERIODIC task cannot \b wait</p>
*/
void testCase15()
{
	fullBuffer=Event_Init();
	Task_Create(Consumer, 0, PERIODIC, 1);
	Task_Create(Producer, 0, RR, 2);
}


/**
 @brief Test Case 16

 @title1{Objective}
 <p>Test RTOS 'event' feature, and the PERIODIC tasks</p>

 @title1{Description}
 <p>For this test case, an event is initialized and 4 tasks are created:<p>
 <ol>
 	<li>Ping1() - PERIODIC Task</li>
	<li>Pong1() - PERIODIC Task</li>
 	<li>Consumer() - SYSTEM Task</li>
	<li>Producer() - RR Task</li>
 </ol>
 
  @title1{Results} @pass
 <p>The RTOS ram the tasks following the PPP array and the event coordination</p>
*/
void testCase16()
{
	fullBuffer=Event_Init();

	Task_Create(Ping1, 0, PERIODIC, 1);
	Task_Create(Pong1, 0, PERIODIC, 2);

	Task_Create(Consumer, 0, SYSTEM, 3);
	Task_Create(Producer, 0, RR, 4);
}


/**
 @brief Test Case 17

 @title1{Objective}
 <p>Test RTOS when a PERIODIC task not defined in the PPP array is created</p>

 @title1{Description}
 <p>For this test case, an event is initialized and 5 tasks are created:<p>
 <ol>
 	<li>Ping1() - PERIODIC Task</li>
	<li>Pong1() - PERIODIC Task</li>
	<li>Ping2() - PERIODIC Task</li>
 	<li>Consumer() - SYSTEM Task </li>
	<li>Producer() - RR Task</li>
 </ol>
 
  @title1{Results} @pass
 <p>The RTOS aborted because the PERIODIC name for the task Ping2() wasn't defined</p>
*/
void testCase17()
{
	fullBuffer=Event_Init();
	Task_Create(Ping1, 0, PERIODIC, 1);
	Task_Create(Pong1, 0, PERIODIC, 2);
	Task_Create(Ping2, 0, PERIODIC, 3);

	Task_Create(Consumer, 0, SYSTEM, 3);
	Task_Create(Producer, 0, RR, 4);
}


/**
 @brief Test Case 18

 @title1{Objective}
 <p>Test RTOS when a PERIODIC task is terminated</p>

 @title1{Description}
 <p>For this test case, 2 tasks are created:<p>
 <ol>
 	<li>Counter1() - PERIODIC Task</li>
	<li>Ping1() - PERIODIC Task</li>
 </ol>
 
  @title1{Results} @pass
 <p>The RTOS executed the tasks as expected. It terminated the Counter1, and continued the execution of Ping1</p>
*/
void testCase18()
{
	Task_Create(Counter1, -10, PERIODIC, 1);
	Task_Create(Ping1, 0, PERIODIC, 2);
}

/**
 @brief Test Case 19

 @title1{Objective}
 <p>Test RTOS when a RR task is put in 'waiting'</p>

 @title1{Description}
 <p>For this test case, an event is initialized, and 4 tasks are created:<p>
 <ol>
 	<li>Consumer() - RR Task</li>
	<li>Producer() - RR Task</li>
	<li>Counter1() - RR Task</li>
	<li>Counter2() - RR Task</li>
 </ol>
 
  @title1{Results} @pass
 <p>The RTOS executed the tasks as expected, and it added the Producer task at the end of the 'queue' when signal to 'ready'</p>

*/
void testCase19()
{
	fullBuffer=Event_Init();

	Task_Create(Consumer, 0, RR, 1);
	Task_Create(Producer, 0, RR, 2);
	Task_Create(Counter1, 1, RR, 3);
	Task_Create(Counter2, 1, RR, 4);
}

/**
 @brief Test Case 20

 @title1{Objective}
 <p>Try to create PERIODIC tasks without defining the PPP array</p>

 @title1{Description}
 <p>For this test case, 2 tasks are created:<p>
 <ol>
 	<li>Ping1() - PERIODIC Task</li>
	<li>Pong1() - PERIODIC Task</li>
 </ol>
 
  @title1{Results} @pass
 <p>The RTOS aborted as expected, because the PPP array wasn't defined</p>
*/
void testCase20()
{
	Task_Create(Ping1, 0, PERIODIC, 1);
	Task_Create(Pong1, 0, PERIODIC, 2);
}

/**
 @brief Test Case 21

 @title1{Objective}
 <p>Try to execute a PERIODIC task that executes longer than defined in the PPP array</p>

 @title1{Description}
 <p>For this test case, 2 tasks are created:<p>
 <ol>
 	<li>Ping1() - PERIODIC Task</li>
	<li>Loop() - PERIODIC Task</li>
 </ol>
 
  @title1{Results} @pass
 <p>The RTOS aborted as expected, because the Loop task executed longer than expected</p>

*/
void testCase21()
{
	Task_Create(Ping1, 0, PERIODIC, 1);
	Task_Create(Loop, 0, PERIODIC, 2);
}

/**
 @brief Test Case 22

 @title1{Objective}
 <p>Try to use an event withour initialize it</p>

 @title1{Description}
 <p>For this test case, 2 tasks are created:<p>
 <ol>
 	<li>Consumer() - PERIODIC Task</li>
	<li>Producer() - RR Task</li>
 </ol>
 
  @title1{Results} @pass
 <p>The RTOS aborted because the event wasn't initialized</p>
*/
void testCase22()
{
	Task_Create(Consumer, 0, PERIODIC, 1);
	Task_Create(Producer, 0, RR, 2);
}

/**
 @brief Test Case 23

 @title1{Objective}
 <p>Test RTOS when there is 1 PERIODIC tasks.</p>

 @title1{Description}
 <p>For this test case, the PPP array is configured to run 1 task for 5 ticks each, and 1 PERIODIC task is created<p>

  @title1{Results} @pass
 <p>The RTOS ran the 2 tasks alternately according the PPP[] </p>
 
*/
void testCase23()
{
	Task_Create(Ping1, 0, PERIODIC, 1);
}

/*!
 * \brief Main task.
 *
 * This is a SYSTEM task create by the RTOS. This will be the first task executed.
 */
int main()
{
	init_leds();

	initTaskCase(testCase);

	return 1;
}
